package com.zff.controller;


import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.wxpay.sdk.*;
import com.zff.common.Payconfig;
import com.zff.dao.XspxGaojianInfoDao;
import com.zff.dao.XstWxUserDao;
import com.zff.dao.XszpOrderDao;
import com.zff.dao.YsjOrderDao;
import com.zff.entity.XspxGaojianInfo;
import com.zff.entity.XstWxUser;
import com.zff.entity.XszpOrder;
import com.zff.entity.YsjOrder;
import com.zff.service.impl.YsjOrderServiceImpl;
import com.zff.tool.MyWXPayUtil;
import org.apache.commons.lang.RandomStringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundValueOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import java.io.InputStream;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * TODO
 * @version 1.0
 * @author Zff
 * @date 2020/9/3 14:42
 */
@RestController
@RequestMapping("/wxPay")
public class WxPayController {

    @Autowired
    private YsjOrderServiceImpl ysjOrderService;

    @Autowired
    private YsjOrderDao ysjOrderDao;

    @Autowired
    private XstWxUserDao xstWxUserDao;

    @Autowired
    private XspxGaojianInfoDao xspxGaojianInfoDao;

    @Autowired
    private XszpOrderDao xszpOrderDao;

    @Autowired
    RedisTemplate<String, Object> redisTemplate;

    String appId = "wx4fcdb7740ea71840";

    String mchId = "1490827062";

    String key = "yuwenbaosheyuwenbaoshe0123456789";

    @GetMapping("/getOpenId")
    public  String getIsVoice(String openid) throws Exception {
        DateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
        String format = dateFormat.format(new Date());
        String s1 = RandomStringUtils.randomNumeric(8);
        String orderNo = s1+format;
        System.out.println("time:"+s1);
        WXPay wxPay = new WXPay(new WXPayConfigCustom());
        Map<String,String> requestParam = new HashMap<>();
        requestParam.put("body","课程");//商品描述
        requestParam.put("out_trade_no",orderNo);//商户订单号
        requestParam.put("fee_type","CNY");//人民币
        requestParam.put("total_fee",String.valueOf(1));//金额
        requestParam.put("spbill_create_ip","127.0.0.1");//客户端IP
        requestParam.put("notify_url","none");
        requestParam.put("trade_type","JSAPI");
        requestParam.put("openid",openid);
        YsjOrder ysjOrder = new YsjOrder();
        ysjOrder.setOrderNo(orderNo);
        ysjOrder.setOpenid(openid);
        ysjOrder.setMchId(mchId);
        ysjOrder.setTotalFee(String.valueOf(1));
        Integer integer = ysjOrderService.insterOrder(ysjOrder);
        System.out.println("订单保存:"+integer);
        Map<String, String> resp = wxPay.unifiedOrder(requestParam);
        String ss = JSONObject.toJSONString(resp);
        System.out.println("ss:"+ss);
        Map<String,String> jsapiPayParam = new HashMap<>();
        jsapiPayParam.put("appId",appId);
        //jsapiPayParam.put("orderNo",orderNo);
        jsapiPayParam.put("timeStamp",System.currentTimeMillis()/1000+"");
        jsapiPayParam.put("nonceStr", UUID.randomUUID().toString());
        jsapiPayParam.put("package","prepay_id="+resp.get("prepay_id"));
        jsapiPayParam.put("signType","HMAC-SHA256");
        jsapiPayParam.put("paySign", WXPayUtil.generateSignature(jsapiPayParam,key,WXPayConstants.SignType.HMACSHA256));
        String s = JSONObject.toJSONString(jsapiPayParam);
        Map<String,String> jsapiOrderNo = new HashMap<>();
        jsapiOrderNo.put("orderNo",orderNo);
        Map<String,String> aa = new HashMap<>();
        aa.putAll(jsapiPayParam);
        aa.putAll(jsapiOrderNo);
        String aass = JSONObject.toJSONString(aa);
        System.out.println("***:"+aass);
        return aass;
    }

    @GetMapping("/getOrderNo")
    public String payOrderWeChat(String orderNo,String openid) throws Exception {

        WXPay wxPay = new WXPay(new WXPayConfigCustom());
        Map<String,String> map = new HashMap<>();
        map.put("out_trade_no",orderNo);
        Map<String, String> result = wxPay.orderQuery(map);
        String return_code = result.get("return_code");
        String return_msg = result.get("return_msg");
        String result_code = result.get("result_code");
        String trade_state = result.get("trade_state");
        String transaction_id = result.get("transaction_id");
        YsjOrder ysjOrder = new YsjOrder();
        ysjOrder.setTransactionId(transaction_id);
        ysjOrder.setTradeState(trade_state);
        ysjOrder.setMsg(return_msg);
        QueryWrapper<YsjOrder> queryWrapper = new QueryWrapper<YsjOrder>();
        queryWrapper.eq("order_no", orderNo);
        System.out.println("orderNo:"+orderNo+"return_code:"+return_code+"return_msg:"+return_msg+"result_code:"+result_code+"trade_state:"+trade_state+"transaction_id"+transaction_id);
        if("SUCCESS".equals(return_code) && "SUCCESS".equals(result_code)){
            if("SUCCESS".equals(trade_state)){//支付成功
                ysjOrderDao.update(ysjOrder,queryWrapper);
                XstWxUser xstWxUser = new XstWxUser();
                QueryWrapper<XstWxUser> xstWxUserQueryWrapper = new QueryWrapper<XstWxUser>();
                xstWxUserQueryWrapper.eq("openId",openid);
                xstWxUser.setStatus("1");
                xstWxUserDao.update(xstWxUser,xstWxUserQueryWrapper);
                HashMap<String, Object> map1 = new HashMap<>();
                map.put("openid",openid);
                List<XstWxUser> xstWxUsers = xstWxUserDao.selectByMap(map1);
                BoundValueOperations<String, Object> user = redisTemplate.boundValueOps(openid);
                user.set(xstWxUsers);
                return "SUCCESS";
            } else if("CLOSED".equals(trade_state)){//交易关闭
                ysjOrderDao.updateById(ysjOrder);
                return "CLOSED";
            } else if("USERPAYING".equals(trade_state)){//支付中
                ysjOrderDao.updateById(ysjOrder);
                return "USERPAYING";
            } else if("PAYERROR".equals(trade_state)){//支付失败
                ysjOrderDao.updateById(ysjOrder);
                return "PAYERROR";
            }
        }
        String aaaaa = JSONObject.toJSONString(result);
        System.out.println("aaaaa"+aaaaa);
        return aaaaa;
    }

    class WXPayConfigCustom extends WXPayConfig{
        @Override
        protected String getAppID() {
            return appId;
        }

        @Override
        protected String getMchID() {
            return mchId;
        }

        @Override
        protected String getKey() {
            return key;
        }

        @Override
        protected InputStream getCertStream() {
            return null;
        }

        @Override
        protected IWXPayDomain getWXPayDomain() {
            return new IWXPayDomain() {
                @Override
                public void report(String s, long l, Exception e) {

                }

                @Override
                public DomainInfo getDomain(WXPayConfig wxPayConfig) {
                    return new DomainInfo(WXPayConstants.DOMAIN_API,true);
                }
            };
        }
    }

    // 调用方式很多，只要你传对参数就行了。
    @GetMapping("/createNative")
    public Map<String,Object> createNative(Integer userId){
        DateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
        String format = dateFormat.format(new Date());
        String s1 = RandomStringUtils.randomNumeric(8);
        String orderNo = s1+format;
        // 生成订单id
        String out_trade_no = orderNo;
        // 金额
        String total_fee = String.valueOf(30000);
        // 前端传来商品id
        String good_id = s1;
        MyWXPayUtil myWXPayUtil = new MyWXPayUtil();
        //调起生成支付二维码
        Map navite = myWXPayUtil.createNavite(out_trade_no, total_fee, good_id);
        System.out.println("navite:"+navite);
        //根据id获取用户信息,要将用户的相关信息存入订单表中
        XstWxUser userInfo = getUserInfoByid(userId);
        //创建订单对象
        XszpOrder xszpOrder = new XszpOrder();
        xszpOrder.setOrderno(out_trade_no);
        xszpOrder.setUserid(userId);
//        xszpOrder.setUsername(userInfo.getUsername());
//        xszpOrder.setPhone(userInfo.getPhone());
//        xszpOrder.setAddress(userInfo.getSchoolArea()+ userInfo.getShippingAddress());
//        xszpOrder.setSchoolname(userInfo.getWorkUnit());
        //新增订单
        int insert = xszpOrderDao.insert(xszpOrder);
        HashMap<String, Object> map = new HashMap<>();
        if(insert == 1){
            return navite;
        } else {
            map.put("states", 0);
            map.put("msg", "新增订单失败");
            return map;
        }
        }

    @GetMapping("/getPayResult")
    public String getPayResult(String out_trade_no,String total_fee,String username,String workstype) {
        String tip = "";
        System.out.println("username:"+username);
        QueryWrapper<XszpOrder> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("orderno",out_trade_no);
        XszpOrder xszpOrder = xszpOrderDao.selectOne(queryWrapper);
        Integer userid = xszpOrder.getUserid();
        XstWxUser xstWxUser = xstWxUserDao.selectById(userid);
        String usernamey = xstWxUser.getUsername();
        if(usernamey.equals(username)){
            int tfee = Integer.parseInt(total_fee);
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String format = simpleDateFormat.format(new Date());
            try {
                int num = 0;
                MyWXPayUtil myWXPayUtil = new MyWXPayUtil();
                while (true){
                    Map map = myWXPayUtil.queryPay(out_trade_no);
                    String trade_state = (String) map.get("trade_state");
                    String transactionid = (String) map.get("transaction_id");
                    if(map ==null){
                        tip="支付发生错误";
                        System.out.println(tip);
                        xszpOrder.setTradestate(trade_state);
                        xszpOrder.setMsg("未支付");
                        break;
                    }
                    if(map.get("trade_state").equals("SUCCESS")){
                        tip="ok"; //支付成功后修改订单状态
                        xszpOrder.setTradestate(trade_state);
                        xszpOrder.setTransactionid(transactionid);
                        xszpOrder.setPayTime(format);
                        xszpOrder.setWorkstype(workstype);
                        xszpOrder.setMsg("支付成功");
                        xszpOrder.setJiangxiang("5");
                        xszpOrder.setTotalfee(total_fee);
                        System.out.println(tip);
                        break;
                    }
                    Thread.sleep(3000);
                    num++;
                    if(num >= 30){
                        tip = "支付超时";
                        xszpOrder.setTradestate(trade_state);
                        xszpOrder.setMsg("支付超时");
                        System.out.println(tip);
                        break;
                    }
                }
            } catch (Exception e){
                e.printStackTrace();
            }
        } else {
            return "0";
        }
        xszpOrderDao.updateById(xszpOrder);
        System.out.println(tip);
        return tip;
    }

    /**
     * 获取根据id获取用户信息
     * @param userId
     * @return
     */
    public XstWxUser getUserInfoByid(Integer userId){
        XstWxUser xstWxUser = xstWxUserDao.selectById(userId);
        if(xstWxUser != null){
            System.out.println("成功查询到用户");
            return xstWxUser;
        } else {
            System.out.println("用户不存在");
            return null;
        }
    }




}
